package server;

import java.io.*;

//Reference:
//https://blog.csdn.net/briblue/article/details/54973413
public class MiniClassLoader extends ClassLoader {
    public void loadClassesFromBasePath(String basePath) throws IOException {
        File baseDir = new File(basePath);

        if (!baseDir.isDirectory()) {
            return;
        }

        File[] files = baseDir.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                loadFromDir(file, file.getName());
            }
            else {
                if (file.getName().endsWith(".class")) {
                    loadFromFile(file, getClassName(file.getName()), "");
                }
            }
        }
    }

    private String getClassName(String name) {
        //Lagou.class->Lagou
        return name.substring(0, name.lastIndexOf(".class"));
    }

    private void loadFromDir(File dir, String baseName) throws IOException {
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                loadFromDir(file,baseName + "." + file.getName());
            }
            else {
                loadFromFile(file, baseName + "." + getClassName(file.getName()),
                        baseName);
            }
        }
    }

    private void loadFromFile(File classFile, String className, String baseName) throws IOException {
//        try {
//            if (this.findClass(className) != null) {
//            }
//        } catch (ClassNotFoundException e) {
            byte[] classData = getBytesFromFile(classFile);
            defineClass(className, classData, 0, classData.length);
//        }
    }

    private byte[] getBytesFromFile(File classFile) throws IOException {
        FileInputStream fis = new FileInputStream(classFile);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] data = new byte[1024];
        int length;
        while ((length = fis.read(data)) != -1) {
            bos.write(data, 0, length);
        }

        return bos.toByteArray();
    }
}
